From 6a535299d62b36683b53f66d6b70de52cee4a0a7 Mon Sep 17 00:00:00 2001
From: Chiranmoy Bhattacharya <chiranmoy.bhattacharya@fujitsu.com>
Date: Mon, 16 Dec 2024 16:33:23 +0530
Subject: [PATCH v1] test module for hex coding

---
 src/test/modules/test_hex_parsing/Makefile    | 21 +++++
 .../test_hex_parsing--1.0.sql                 |  2 +
 .../test_hex_parsing/test_hex_parsing.c       | 86 +++++++++++++++++++
 .../test_hex_parsing/test_hex_parsing.control |  4 +
 4 files changed, 113 insertions(+)
 create mode 100644 src/test/modules/test_hex_parsing/Makefile
 create mode 100644 src/test/modules/test_hex_parsing/test_hex_parsing--1.0.sql
 create mode 100644 src/test/modules/test_hex_parsing/test_hex_parsing.c
 create mode 100644 src/test/modules/test_hex_parsing/test_hex_parsing.control

diff --git a/src/test/modules/test_hex_parsing/Makefile b/src/test/modules/test_hex_parsing/Makefile
new file mode 100644
index 0000000000..21a8ee416e
--- /dev/null
+++ b/src/test/modules/test_hex_parsing/Makefile
@@ -0,0 +1,21 @@
+MODULE_big = test_hex_parsing
+OBJS = test_hex_parsing.o
+PGFILEDESC = "test"
+EXTENSION = test_hex_parsing
+DATA = test_hex_parsing--1.0.sql
+
+first: all
+
+# needed?
+test_hex_parsing.o: test_hex_parsing.c
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/test_hex_parsing
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/test_hex_parsing/test_hex_parsing--1.0.sql b/src/test/modules/test_hex_parsing/test_hex_parsing--1.0.sql
new file mode 100644
index 0000000000..5676e895c2
--- /dev/null
+++ b/src/test/modules/test_hex_parsing/test_hex_parsing--1.0.sql
@@ -0,0 +1,2 @@
+CREATE FUNCTION hex_encode_test(count int, num int) RETURNS text AS 'test_hex_parsing' LANGUAGE C;
+CREATE FUNCTION hex_decode_test(count int, num int) RETURNS text AS 'test_hex_parsing' LANGUAGE C;
\ No newline at end of file
diff --git a/src/test/modules/test_hex_parsing/test_hex_parsing.c b/src/test/modules/test_hex_parsing/test_hex_parsing.c
new file mode 100644
index 0000000000..dea19f365e
--- /dev/null
+++ b/src/test/modules/test_hex_parsing/test_hex_parsing.c
@@ -0,0 +1,86 @@
+/* select hex_encode_test(1000000, 1024); */
+/* select hex_decode_test(1000000, 1024); */
+
+#include "postgres.h"
+#include "fmgr.h"
+#include "utils/builtins.h"
+
+PG_MODULE_MAGIC;
+
+#ifndef HEX_ENCODE
+#define HEX_ENCODE(src, len, dst) hex_encode(src, len, dst)
+#endif
+
+#ifndef HEX_DECODE
+#define HEX_DECODE(src, len, dst) hex_decode(src, len, dst)
+#endif
+
+#define TRUNCATE 1	/* if true output min(len, 8) characters */
+
+/*
+ * hex_encode_test(count int, len int) returns text
+ * count: the number of iterations
+ * len: the number of bytes to encode
+ */
+PG_FUNCTION_INFO_V1(hex_encode_test);
+Datum
+hex_encode_test(PG_FUNCTION_ARGS)
+{
+	/* DEADC0DEBAADF00DC001C0FFEE in bytes */
+	uint8		bytes[]	= {222, 173, 192, 222, 186, 173, 240, 13, 192, 1, 192, 255, 238};
+	int			count 	= PG_GETARG_INT32(0);
+	int			len		= PG_GETARG_INT32(1);
+	char	   *src		= palloc(len);
+	char	   *dst 	= palloc(len * 2 + 1);
+	uint64		encoded_len;
+
+	dst[len * 2] = '\0';
+
+	for (int i = 0; i < len; i++)
+		src[i] = bytes[i % 13];
+
+	while (count--)
+		encoded_len = HEX_ENCODE(src, len, dst);
+
+	if (TRUNCATE)
+		dst[Min(len, 8)] = '\0';
+
+	PG_RETURN_TEXT_P(cstring_to_text(dst));
+}
+
+/*
+ * hex_decode_test(count int, len int) returns text
+ * count: the number of iterations
+ * len: the number of hex digits to decode, len should be even
+ */
+PG_FUNCTION_INFO_V1(hex_decode_test);
+Datum
+hex_decode_test(PG_FUNCTION_ARGS)
+{
+	char	   *hex_chr	= "DEADC0DEBAADF00DC001C0FFEE";
+	int			count 	= PG_GETARG_INT32(0);
+	int			len		= PG_GETARG_INT32(1);
+	int 		encode_len;
+	char	   *encoded;
+	char	   *src		= palloc(len);
+	char	   *dst		= palloc(len / 2);
+	uint64		decoded_len;
+
+	for (int i = 0; i < len; i++)
+		src[i] = hex_chr[i % 26];
+
+	while (count--)
+		decoded_len = HEX_DECODE(src, len, dst);
+
+	/* convert back to hex for printing */
+	if(TRUNCATE)
+		encode_len = Min(len / 2, 4);
+	else
+		encode_len = len / 2;
+
+	encoded = palloc(encode_len * 2 + 1);
+	encoded[encode_len * 2] = '\0';
+
+	HEX_ENCODE(dst, encode_len, encoded);
+	PG_RETURN_TEXT_P(cstring_to_text(encoded));
+}
diff --git a/src/test/modules/test_hex_parsing/test_hex_parsing.control b/src/test/modules/test_hex_parsing/test_hex_parsing.control
new file mode 100644
index 0000000000..c48ee81998
--- /dev/null
+++ b/src/test/modules/test_hex_parsing/test_hex_parsing.control
@@ -0,0 +1,4 @@
+comment = 'test'
+default_version = '1.0'
+module_pathname = '$libdir/test_hex_parsing'
+relocatable = true
-- 
2.34.1

